﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Didaku.Attributes;
using Didaku.Collections;
using Didaku.QEngine.Common.Interfaces.Entities;
using Didaku.QEngine.Common.Wrapper;

namespace Didaku.QEngine.Common.Abstracts.Entities
{
    /// <summary>业务类型
    /// </summary>
    [Serializable]
    public abstract class BusinessTypeInfo : IBusinessType<BusinessTypeCategoryInfo>
    {
        protected BusinessTypeInfo()
        {
            Id = Guid.NewGuid();
        }

        #region IBusinessType<BusinessTypeCategoryInfo> Members

        /// <summary>业务类型的全局ID。保证业务类型的唯一性。
        /// </summary>
        [Key]
        [EntityColumn]
        public Guid Id { get; set; }

        /// <summary>业务编号
        /// </summary>
        /// <value>
        /// The id.
        /// </value>
        [EntityColumn]
        public string Number { get; set; }

        /// <summary>工作时间段集合
        /// </summary>
        public ICollection<WorkRange> WorkRanges { get; set; }

        /// <summary>业务名称
        /// </summary>
        [EntityColumn]
        public string Name { get; set; }

        /// <summary>
        /// 业务分类延迟加载
        /// </summary>
        [EntityColumn]
        public virtual BusinessTypeCategoryInfo Category { get; set; }

        /// <summary>
        /// 业务类型的其他相关属性信息集合
        /// </summary>
        [EntityColumn]
        public SerializableMap<string, string> Details { get; set; }

        /// <summary>
        /// Indicates whether the current object is equal to another object of the same type.
        /// </summary>
        /// <returns>
        /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
        /// </returns>
        /// <param name="other">An object to compare with this object.</param>
        public bool Equals(IBusinessType<BusinessTypeCategoryInfo> other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return Equals(other.Id, Id) && Equals(other.Number, Number);
        }

        #endregion

        #region override

        public abstract object Clone();

        public override string ToString()
        {
            return string.Format("{0}.{1}", Number, Name);
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != typeof (BusinessTypeInfo)) return false;
            return Equals((BusinessTypeInfo) obj);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                return (Id.GetHashCode()*397) ^ Number.GetHashCode();
            }
        }

        public static bool operator ==(BusinessTypeInfo left, BusinessTypeInfo right)
        {
            return Equals(left, right);
        }

        public static bool operator !=(BusinessTypeInfo left, BusinessTypeInfo right)
        {
            return !Equals(left, right);
        }

        #endregion
    }
}